<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <title>原生JS兼容移动端-轮播图</title>
  <style>
    *,
    ::before,
    ::after{
      padding: 0;
      margin: 0;
      box-sizing: border-box;
      -webkit-box-sizing: border-box;
      -webkit-tap-highlight-color: transparent;/*清除移动端点击高亮效果*/
    }
    body{
      font-family:Microsoft YaHei,sans-serif;
      font-size: 14px;
      color: #333;
    }
    ol,ul{
      list-style: none;
    }
    /*清除浮动*/
    .clearfix::before,
    .clearfix::after{
      content: "";
      display: block;
      height: 0;
      line-height: 0;
      visibility: hidden;
      clear: both;
    }

    .carousel{
      width: 100%;
      max-width: 750px;
      min-width: 320px;
      margin: 0 auto;
      position: relative;
    }
    #banner{
      width: 100%;
      overflow: hidden;
      position: relative;
    }
    #banner ul:first-child{
      width: 1000%;
      transform: translateX(-10%);
      -o-transform: translateX(-10%);
      -ms-transform: translateX(-10%); /* IE 9 */
      -moz-transform: translateX(-10%);
      -webkit-transform: translateX(-10%);
      overflow: hidden;
    }
    #banner ul:first-child li{
      width: 10%;
      float: left;
      box-sizing: border-box;
    }

    #banner ul:first-child li a{
      display: block;
      width: 100%;
      position: relative;
    }
    #banner ul:first-child li a span{
      left: 50%;
      position: absolute;
      font-size: 40px;
      text-align: center;
      display: block;
      top: 50%;
      transform: translate(-50%,-50%);
      color: red;
    }
    #banner ul:first-child li a img{
      width: 100%;
      display: block;
    }
    #banner ul:last-child{
      position: absolute;
      bottom: 6px;
      width: 100%;
      text-align: center;
    }
    #banner ul:last-child li{
      width: 6px;
      height: 6px;
      border: 1px solid #fff;
      border-radius: 50%;
      display: inline-block;
      margin-left: 10px;
    }
    #banner ul:last-child li:first-child{
      margin-left: 0;
    }
    #banner ul:last-child li.now{
      background: red;
    }

    /*左右切换*/
    .switchBtn{
      position: absolute;
      width: 6%;
      top: 50%;
      box-sizing: border-box;
      cursor: pointer;
    }
    .switchBtn img{
      display: block;
      width: 100%;
      opacity: .35;
    }
    .switchBtn:hover img{
      opacity: .85;
    }
    #prevBtn{
      left: 20px;
      transform: scaleX(-1) translate(0,-50%);
      -o-transform: scaleX(-1) translate(0,-50%);
      -ms-transform: scaleX(-1) translate(0,-50%);
      -moz-transform: scaleX(-1) translate(0,-50%);
      -webkit-transform: scaleX(-1) translate(0,-50%);
    }
    #nextBtn{
      right: 20px;
      transform: translate(0,-50%);
      -o-transform: translate(0,-50%);
      -ms-transform: translate(0,-50%);
      -moz-transform: translate(0,-50%);
      -webkit-transform: translate(0,-50%);
    }
  </style>
</head>
<body>
<div class="carousel">
  <div id="banner">
    <ul class="clearfix slide">
      <li><a href="#"><img src="images/1.jpg"><span>1</span></a></li>
      <li><a href="#"><img src="images/2.jpg"><span>2</span></a></li>
      <li><a href="#"><img src="images/3.jpg"><span>3</span></a></li>
      <li><a href="#"><img src="images/4.jpg"><span>4</span></a></li>
      <li><a href="#"><img src="images/5.jpg"><span>5</span></a></li>
      <li><a href="#"><img src="images/6.jpg"><span>6</span></a></li>
      <li><a href="#"><img src="images/7.jpg"><span>7</span></a></li>
      <li><a href="#"><img src="images/8.jpg"><span>8</span></a></li>
    </ul>
    <!--左右切换箭头-->
    <span class="switchBtn" id="prevBtn"><img src="images/arrow.png" class="prevArrow" alt=""></span>
    <span class="switchBtn" id="nextBtn"><img src="images/arrow.png" class="nextArrow" alt=""></span>
    <!--轮播索引的点-->
    <ul class="ctrl"></ul>
  </div>
</div>
<script>
  window.onload = function(){
    var banner = document.getElementById('banner');//轮播盒子
    var width = banner.offsetWidth;
    var imageBox = banner.querySelector('ul.slide');
    var imageCount = imageBox.querySelectorAll('li').length; //图片张数
    var pointBox = banner.querySelector('ul.ctrl');//点盒子
    var prevBtn = document.getElementById("prevBtn"); //向左按钮
    var nextBtn = document.getElementById("nextBtn"); //向右按钮

    var index = 1; //默认开始的图片位置
    var moveSpeed = 2000;//轮播速度
    //动态添加索引
    for(var i = 0;i<imageCount;i++){
      var li = document.createElement("li");
      pointBox.appendChild(li);
      if(i == 0){
        //默认第一个点高亮
        li.className="now"
      }
    }
    var points = pointBox.querySelectorAll('li');//所有的点

  //在第一张前面添加最后一张，最后一张后面添加第一张，防止切换到首尾时出现空白
    var slideFirst = imageBox.querySelector('li:first-child');
    var newLast = slideFirst.cloneNode(true);//复制第一张
    imageBox.appendChild(newLast);//在最后面添加第一张
    var slideLast = imageBox.querySelector('li:nth-last-of-type(2)');//最后一张图片，此时已经在最后面添加了第一张
    var newFirst = slideLast.cloneNode(true);//复制最后一张
    prependChild(imageBox,newFirst);//在最前添加最后一张

    //在最前添加最后一张的方法
    function prependChild(parent,newChild){
      if(parent.firstChild){
        parent.insertBefore(newChild,parent.firstChild);
      } else {
        parent.appendChild(newChild);
      }
      return parent;
    }
    //加过渡
    var addTransition = function(){
      imageBox.style.transition = "all 0.3s";
      imageBox.style.oTransition = "all 0.3s";
      imageBox.style.msTransition = "all 0.3s";
      imageBox.style.mozTransition = "all 0.3s";
      imageBox.style.webkitTransition = "all 0.3s";
    };
    //清除过渡
    var removeTransition = function(){
      imageBox.style.transition = "none";
      imageBox.style.oTransition = "none";
      imageBox.style.msTransition = "none";
      imageBox.style.mozTransition = "none";
      imageBox.style.webkitTransition = "none";
    };
    //定位
    var setTranslateX = function(translateX){
      imageBox.style.transform = "translateX("+translateX+"px)";
      imageBox.style.oTransform = "translateX("+translateX+"px)";
      imageBox.style.msTransform = "translateX("+translateX+"px)";
      imageBox.style.mozTransform = "translateX("+translateX+"px)";
      imageBox.style.webkitTransform = "translateX("+translateX+"px)";
    };

//    判断是否动画结束
    function transitionEnd(dom,callback){
      if(!dom || typeof dom != 'object'){
        return false;
      }
      dom.addEventListener('transitionend', function(){
        callback && callback();
      });
      dom.addEventListener('transitionEnd', function(){
        callback && callback();
      });
      dom.addEventListener('oTransitionEnd', function(){
        callback && callback();
      });
      dom.addEventListener('msTransitionEnd', function(){
        callback && callback();
      });
      dom.addEventListener('mozTransitionEnd', function(){
        callback && callback();
      });
      dom.addEventListener('webkitTransitionEnd', function(){
        callback && callback();
      });
    }
    var timer = null;
//    轮播动画
    function  setTime(){
      timer = setInterval(function(){
        index ++;
        addTransition();
        setTranslateX(-index * width);
        transitionEnd(imageBox,function(){
          if(index == imageCount){
            removeTransition();
            index = 0;
            setTranslateX(-index * width);
          }
        });
        setPoint();
      },moveSpeed);
    }
    setTime();

    //当前图片对应的点高亮
    var setPoint = function(){
      for(var i = 0 ; i < points.length ; i++){
        points[i].className = " ";
      }
      if(index == 0){
        points[imageCount-1].className = "now";
      }
      if(index == imageCount+1){
        points[0].className = "now";
      }
      if(index <= imageCount){
        points[index-1].className = "now";
      }
    };

    //touch事件
    var startX = 0; //记录起始x的坐标
    var moveX = 0;  //滑动的时候x的位置
    var distanceX = 0;  //滑动的距离
    var isMove = false; //是否滑动过
    imageBox.addEventListener('touchstart', function(e){
      startX = e.touches[0].clientX;  //记录起始X
    });
    imageBox.addEventListener('touchmove',function(e){
      moveX = e.touches[0].clientX;   //滑动时候的X
      distanceX = moveX - startX; //计算移动的距离
      removeTransition();
      clearInterval(timer);
      setTranslateX(-index * width + distanceX);  //实时的定位
      isMove = true;
    });
    imageBox.addEventListener('touchend', function(e){
      // 滑动超过 1/3 即为滑动有效，否则即为无效，则吸附回去
      setTime();//避免滑过1/3 又手动划回去而导致轮播结束
      if(isMove && Math.abs(distanceX) > width/3){
        clearInterval(timer);
        //滑动有效时
        if(distanceX > 0){
          //上一张
          prevBtn.click();
        }
        else{
          //下一张
          nextBtn.click();
        }
      }
      addTransition();
      setTranslateX(-index * width);
      setPoint();
      //重置参数
      startX = 0;
      moveX = 0;
      distanceX = 0;
      isMove = false;
    });

    //  左右箭头的切换
    var flag = true;//防止快速点击，需在动画结束后可再次点击
    //  左点击
    prevBtn.onclick = function(){
      if(flag){
        flag = false;
        clearInterval(timer);
        index --;
        addTransition();
        setTranslateX(-index * width);
        transitionEnd(imageBox,function(){
          flag = true; // 可再次点击
          if(index == 0){
            removeTransition();
            index = imageCount;
            setTranslateX(-index * width);
          }
        });
        /**/
        setTimeout(function(){
          setTime();
          setPoint();
        },300);
      }
    };
    //  右点击
    nextBtn.onclick = function(){
      if(flag){
        flag = false;
        clearInterval(timer);
        index ++;
        addTransition();
        setTranslateX(-index * width);
        transitionEnd(imageBox,function(){
          flag = true;//可再次点击
          if(index == imageCount+1){
            removeTransition();
            index = 1;
            setTranslateX(-index * width);
          }
        });
        setTimeout(function(){
          setTime();
          setPoint();
        },300);
      }
    };

    //  点击索引的点
    var ctrl = document.getElementsByClassName("ctrl")[0];
    var ctrlLi = ctrl.querySelectorAll("li");
      for (var i = 0;i < ctrlLi.length; i++) {
        ctrlLi[i].index = i;
        ctrlLi[i].onclick=function(){
          clearInterval(timer);
          index = this.index + 1;
          addTransition();
          setTranslateX(-index * width);
          setPoint();
          setTime();
        }
      }
  };
</script>
</body>
</html>